﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
using MOCSoftware.Utilities.JpgMetaDataViewer.Model;
using MOCSoftware.Utilities.JpgMetaDataViewer.Utility;

namespace MOCSoftware.Utilities.JpgMetaDataViewer.Viewmodel
{
    internal class MetaDataViewModel : ViewModelBase
    {
        private JpgManager _jpgManaer;

        public ObservableCollection<KeyValuePair<string, string>> MicrosoftMetaData { get; private set; }
        public ObservableCollection<KeyValuePair<string, string>> ExifMetaData { get; private set; }

        private Visibility _visibility;

        public Visibility Visibility
        {
            get { return _visibility; }
            private set
            {
                _visibility = value;
                OnPropertyChanged("Visibility");
            }
        }

        public MetaDataViewModel(JpgManager jpgManager)
        {
            _jpgManaer = jpgManager;
            _jpgManaer.FileLoadDialogueFileSelectedHandler += OnFileLoadDialogueFileSelected;
            MicrosoftMetaData = new ObservableCollection<KeyValuePair<string, string>>();
            ExifMetaData = new ObservableCollection<KeyValuePair<string, string>>();
            _visibility = Visibility.Hidden;
        }

        internal override void Initialise()
        {
        }


        private void OnFileLoadDialogueFileSelected(object source, FileLoadDialogueFileSelectedEventArgs e)
        {
            Visibility = Visibility.Visible;
            MicrosoftMetaData.Clear();
            ExifMetaData.Clear();

            var imageStream = new FileStream(e.FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            var decoder = new JpegBitmapDecoder(imageStream, BitmapCreateOptions.PreservePixelFormat,
                BitmapCacheOption.Default);
            var metaData = (BitmapMetadata) decoder.Frames[0].Metadata;
            if (metaData != null)
            {
                GetMicrosoftMetaDataAttributes(metaData);
                GetExifMetaDataAttributes(metaData);
            }

            imageStream.Dispose();
        }

        private void GetMicrosoftMetaDataAttributes(BitmapMetadata metaData)
        {
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Application Name", metaData.ApplicationName));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Camera Manufacturer", metaData.CameraManufacturer));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Camera Model", metaData.CameraModel));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Comment", metaData.Comment));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Copyright", metaData.Copyright));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Date Taken", metaData.DateTaken));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Format", metaData.Format));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Location", metaData.Location));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Subject", metaData.Subject));
            MicrosoftMetaData.Add(new KeyValuePair<string, string>("Title", metaData.Title));
            if (metaData.Author != null)
                MicrosoftMetaData.Add(new KeyValuePair<string, string>("Author", string.Join(", ", metaData.Author)));
        }

        private void GetExifMetaDataAttributes(BitmapMetadata metaData)
        {
            var attributes = (ExifAttributes[])Enum.GetValues(typeof(ExifAttributes));
            var attributeCollection = new List<KeyValuePair<string, string>>();
            foreach (var attribute in attributes)
            {
                var attributeName = attribute.GetDescription();
                var metadDataQueryResult = metaData.GetQuery(@"/app1/ifd/{ushort=" + (int)attribute + "}");
                if (metadDataQueryResult == null)
                    metadDataQueryResult = metaData.GetQuery(@"/app1/ifd/exif/{ushort=" + (int)attribute + "}");
                attributeCollection.Add(new KeyValuePair<string, string>(attributeName, string.Format("{0}", metadDataQueryResult)));
            }
            foreach (var item in attributeCollection.OrderBy(pair => pair.Key))
            {
                ExifMetaData.Add(item);
            }
        }
    }
}
